本篇是故事二的「查證」篇。
本篇要回答:懷疑執行環境不一致時,應該保存哪些證據,才能讓討論建立在事實上?
Day 06 抓到了「兩個 Python 輪班」的第一個證據,但只有一條路徑還不夠。要回答「套件裝到哪去了」「測試到底跑在哪個環境」,需要一份完整的身分調查——對象不只 python,還包括 pip 與 pytest,因為這三個名字完全可能各自指向不同地方。
過去的習慣是憑感覺記環境:「這台是 3.11」「這個專案有 venv」。感覺的問題在於它不可對質——出事時你只能說「我記得」,而 Day 17 會再回來打這個臉:回憶只能當線索,不能當物證。
建立採證清單,IDE 與 Terminal 各跑一輪,輸出存檔:
python --version
python -c "import sys; print(sys.executable)"
python -c "import sys; print(sys.prefix); print(sys.base_prefix)"
python -m pip --version
python -m pytest --version
Windows 再補上「這個名字實際解析到哪個執行檔」:
Get-Command python
Get-Command pytest
where.exe python
where.exe pytest
判讀重點有三個。第一,sys.executable 是「現在說話的 Python」的完整路徑,兩邊不同就是兩個環境。第二,sys.prefix 與 sys.base_prefix 相同代表沒有啟用虛擬環境,不同代表在 venv 裡(示意輸出格式:系統環境會印出兩行相同的路徑,如 /usr 與 /usr)。第三,python -m pip --version 印出的是「這個 Python 的 pip」,跟直接打 pip 找到誰是兩回事——where.exe pytest 找到的執行檔,也不一定屬於眼前這個 Python。
除了指令輸出,同時保存:IDE 設定的 interpreter 完整路徑、IDE 實際執行測試的命令(多數 IDE 的測試視窗會顯示)、Terminal 的 PATH、虛擬環境啟用狀態、Python 與 pip 與 pytest 與關鍵套件版本、專案工作目錄。
區分證據等級。已確認事實:上述指令的行為與判讀方式(可在任何機器重現)。去識別化說明:當時兩邊的實際路徑與版本值不再列出,文章以判讀方法為主。
留下這份環境採證清單,以及一條順序原則:
在開始重新安裝套件以前,先要求每一個工具報出自己的完整身分。
重裝是最誘人的動作,因為它有進度感;但在身分不明時重裝,等於在不知道哪個口袋破洞的情況下繼續往口袋裡塞錢。
下一篇(Day 08)把兩邊的採證結果並排——問題會第一次完整現形。